home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / command.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-23  |  19.5 KB  |  753 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record
  3.  * Copyright (C) 1993 by Charles Sandmann (sandmann@clio.rice.edu)
  4.  * 
  5.  * This file is part of ED.
  6.  * 
  7.  * ED is free software; you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation.
  9.  * 
  10.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  11.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  13.  * 
  14.  * You should have received a copy of the GNU General Public License along with ED
  15.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  16.  * Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18. #include "opsys.h"
  19.  
  20. #include <stdio.h>
  21. #include <time.h>
  22. #include <string.h>
  23.  
  24. #include "unistd.h"
  25. #include "ctyp_dec.h"
  26. #include "rec.h"
  27. #include "window.h"
  28. #include "ed_dec.h"
  29. #include "buffer.h"
  30. #include "buf_dec.h"
  31. #include "cmd_enum.h"
  32. #include "cmd_def.h"
  33. #include "keyvals.h"
  34.  
  35. extern Char *filename();
  36. extern Char *insstr();
  37. #ifndef NO_FTP
  38. extern Char *host_filename();
  39. #endif
  40.  
  41. #ifdef VMS
  42. typedef struct desc_str
  43. {
  44.     unsigned short length,class;
  45.     Char *string;
  46. } desc_node;
  47. #endif
  48.  
  49. /******************************************************************************\
  50. |Routine: parse_string
  51. |Callby: command
  52. |Purpose: Parses a token from a command, skipping the command itself.
  53. |Arguments:
  54. |    buf - the command buffer.
  55. |    l - the length of the command buffer.
  56. \******************************************************************************/
  57. Char *parse_string(buf,l)
  58. register Char *buf;
  59. Int l;
  60. {
  61.     register Char *end;
  62.     
  63.     end = buf + l;
  64.     while(buf != end && !isspace(*buf))    /* skip nonblank characters (they are part of the command) */
  65.         buf++;
  66.     if(buf != end)
  67.         while(buf != end && isspace(*buf))    /* skip blank characters */
  68.             buf++;
  69.     return(buf);
  70. }
  71.  
  72. /******************************************************************************\
  73. |Routine: parse_decimal
  74. |Callby: command
  75. |Purpose: Parses a decimal number value from a command.
  76. |Arguments:
  77. |    buf - the command buffer.
  78. |    l - the length of the command buffer.
  79. \******************************************************************************/
  80. Int parse_decimal(buf,l)
  81. Char *buf;
  82. Int l;
  83. {
  84.     Char *p;
  85.     Int i;
  86.     
  87.     p = parse_string(buf,l);
  88.     if(!strlen(p))
  89.         return(0);    /* 0 is the default */
  90.     if(my_sscanf(p,"%d",&i) == 1)
  91.         return(i);
  92.     bell();
  93.     return(0);
  94. }
  95.  
  96. /******************************************************************************\
  97. |Routine: command
  98. |Callby: edit
  99. |Purpose: Implements the command interface. Returns 1 when they EXIT, QUIT or
  100. |         ABORT. Returns -1 when they EXIT when posting. Returns -2 when they
  101. |         QUIT or ABORT when posting.
  102. |Arguments:
  103. |    grepdata is an array of GREP'ed buffers.
  104. |    greptitle is an array of titles of GREP'ed buffers.
  105. \******************************************************************************/
  106. Int command(grepdata,greptitle)
  107. rec_ptr *grepdata;
  108. Char **greptitle;
  109. {
  110.     Int i,j,l,choice,count,save_curwindow;
  111.     Char buf[512],*a,*b,*c,title[512],fname[512],bookbuf[512],fname2[512];
  112.     time_t t;
  113.     rec_node r,*base,*p,*q;
  114.     buf_node multibuf;    /* buffer for insertion of repeated chars */
  115.     rec_node multirec;
  116. #ifdef VMS
  117.     desc_node desc;
  118. #endif
  119.  
  120.     switch(choice = parse_command("Command",buf,sizeof(buf),&l,&i,commands,NUM_COMMANDS,"command"))
  121.     {
  122.         case COM_EXIT:
  123.             unselect();
  124.             save_window();    /* so bookmark code has up-to-date WINDOW[[i].currec */
  125.             if(WINDOW[0].diredit)
  126.                 return(1);
  127. /* if a posting window is present, return special value */
  128.             for(i = 0;i < NWINDOWS;i++)
  129.                 if(WINDOW[i].news == 4)
  130.                     return(-1);
  131. #ifndef NO_NEWS
  132.             if(WINDOW[0].news)    /* rewrite .newsrc */
  133.             {
  134.                 if(newsrc_save())
  135.                     return(1);
  136.                 return(0);
  137.             }
  138. #endif
  139.             if(insstr(buf," -n") || insstr(buf,"-n "))
  140.                 set_output_nobak();
  141.             if((i = output_file(0,0)) >= 0)
  142.             {
  143.                 marge(1,NROW);
  144.                 FIRSTCOL = 1;
  145.                 move(NROW,1);
  146.                 next();
  147.                 reverse();
  148.                 strcpy(fname,WINDOW[0].filename);
  149. #ifdef VMS
  150.                 if((a = strchr(fname,';')))
  151.                     *a = '\0';
  152. #endif
  153.                 sprintf(buf,"%s, %d records.",WINDOW[0].filename,i);
  154.                 putz(buf);
  155.                 normal();
  156.                 putout();
  157.                 return(1);
  158.             }
  159.             break;
  160.         case COM_QUIT:
  161.             save_window();    /* so bookmark code has up-to-date WINDOW[[i].currec */
  162. /* if a posting window is present, return special value */
  163.             for(i = 0;i < NWINDOWS;i++)
  164.                 if(WINDOW[i].news == 4)
  165.                     return(-2);
  166.             return(1);
  167.         case COM_HELP:
  168.             help(buf + i);
  169.             break;
  170.         case COM_SET:
  171.             if((choice = parse_command(NULL,buf,sizeof(buf),&l,&i,params,NUM_PARAMS,"parameter")) < -1)
  172.                 return(0);
  173.             else if(choice == -1)
  174.                 choice = parse_command("Set what",buf,sizeof(buf),&l,&i,params,NUM_PARAMS,"parameter");
  175.             if(choice >= 0 && choice < NUM_PARAMS - NUM_NOTSETTABLE)    /* ignore SET KEYS, POSI, MODI */
  176.                 set_param(choice,buf,sizeof(buf),l,i);
  177.             break;
  178.         case COM_SHOW:
  179.             if((choice = parse_command(NULL,buf,sizeof(buf),&l,&i,params,NUM_PARAMS,"parameter")) < -1)
  180.                 return(0);
  181.             if(choice >= -1 && choice < NUM_PARAMS - 1)    /* ignore SHOW KEYS */
  182.                 show_param(choice);
  183.             break;
  184.         case COM_STORE:
  185.             if((choice = parse_command(NULL,buf,sizeof(buf),&l,&i,params,NUM_PARAMS,"parameter")) < -1)
  186.                 return(0);
  187.             store_param(choice);
  188.             break;
  189.         case COM_RESTORE:
  190.             if((choice = parse_command(NULL,buf,sizeof(buf),&l,&i,params,NUM_PARAMS,"parameter")) < -1)
  191.                 return(0);
  192.             restore_par(choice);
  193.             if(choice == 0 || choice == -1)
  194.                 ref_display();
  195.             break;
  196.         case COM_INCLUDE:
  197.             if(WINDOW[CURWINDOW].diredit)
  198.             {
  199.                 bell();
  200.                 slip_message("You can't INCLUDE a file in a directory listing.");
  201.                 wait_message();
  202.                 break;
  203.             }
  204.             if(strlen(a = parse_string(buf + i,l - i)))    /* parse include file name */
  205.                 strcpy(fname,a);
  206.             else
  207.             {
  208.                 if((l = inquire("File to include",buf,sizeof(buf),1)) > 0)
  209.                     strcpy(fname,buf);
  210.                 else
  211.                     fname[0] = '\0';
  212.             }
  213.             if(fname[0])
  214.             {
  215.                 strip_quotes(fname);
  216.                 include_file(fname,WINDOW[CURWINDOW].binary);    /* calls load_file(), which calls envir_subs() */
  217.             }
  218.             break;
  219.         case COM_WRITE:
  220.             if(WINDOW[CURWINDOW].diredit)
  221.             {
  222.                 bell();
  223.                 slip_message("You cannot WRITE a directory, sorry.");
  224.                 wait_message();
  225.                 break;
  226.             }
  227.             if(strlen(a = parse_string(buf + i,l - i)))    /* parse write-to file name */
  228.             {
  229.                 strcpy(fname,a);
  230.                 strip_quotes(fname);
  231.                 envir_subs(fname);
  232.                 output_file(fname,CURWINDOW);
  233.             }
  234.             else
  235.             {
  236.                 unselect();
  237.                 output_file(0,CURWINDOW);
  238.             }
  239.             break;
  240.         case COM_CALCULATE:
  241.             if(!calculate(CURREC->data,buf))
  242.                 abort_key();
  243.             buffer_empty(&KILLBUF);
  244.             r.next = &r;
  245.             r.prev = &r;
  246.             r.length = strlen(buf);
  247.             r.data = (Char *)imalloc(r.length+1);
  248.             strcpy(r.data,buf);
  249.             buffer_append(&KILLBUF,&r,0,r.length);
  250.             KILLBUF.nrecs = KILLBUF.direction = 1;
  251.             ifree(r.data);
  252.             break;
  253.         case COM_DATE:
  254.             t = time(0);
  255.             a = (Char *)ctime(&t);
  256.             sprintf(buf,"%2.2s-%3.3s-%4.4s",a+8,a+4,a+20);
  257.             buffer_empty(&KILLBUF);
  258.             r.next = &r;
  259.             r.prev = &r;
  260.             r.length = strlen(buf);
  261.             r.data = (Char *)imalloc(r.length+1);
  262.             strcpy(r.data,buf);
  263.             buffer_append(&KILLBUF,&r,0,r.length);
  264.             KILLBUF.nrecs = KILLBUF.direction = 1;
  265.             ifree(r.data);
  266.             break;
  267.         case COM_TIME:
  268.             t = time(0);
  269.             a = (Char *)ctime(&t);
  270.             sprintf(buf,"%8.8s",a+11);
  271.             buffer_empty(&KILLBUF);
  272.             r.next = &r;
  273.             r.prev = &r;
  274.             r.length = strlen(buf);
  275.             r.data = (Char *)imalloc(r.length+1);
  276.             strcpy(r.data,buf);
  277.             buffer_append(&KILLBUF,&r,0,r.length);
  278.             KILLBUF.nrecs = KILLBUF.direction = 1;
  279.             ifree(r.data);
  280.             break;
  281.         case COM_ABORT:
  282.             save_window();    /* so bookmark code has up-to-date WINDOW[[i].currec */
  283.             file_list_abort();    /* make file_list_next() fail */
  284.             abort_parsing();    /* make parse_filename() fail */
  285.             parse_skip(0);    /* insure special no-prompt parse_filename state is reset */
  286.             cancel_multiple();    /* insure not in multiple-mode */
  287. /* if a posting window is present, return special value */
  288.             for(i = 0;i < NWINDOWS;i++)
  289.                 if(WINDOW[i].news == 4)
  290.                     return(-2);
  291.             return(1);
  292.         case COM_GREP:
  293.         case COM_PERG:
  294.             if(!strlen(a = parse_string(buf + i,l - i)))    /* parse search string */
  295.             {
  296.                 if(!(l = inquire("String to search for",buf,sizeof(buf),1)))
  297.                     break;
  298.                 a = buf;
  299.             }
  300.             if(NWINDOWS >= MAX_WINDOWS)
  301.             {
  302.                 slip_message("You must close a window first.");
  303.                 wait_message();
  304.                 break;
  305.             }
  306.             unselect();
  307.             paint(BOTROW,BOTROW,FIRSTCOL);
  308.             base = (rec_ptr)imalloc(sizeof(rec_node));
  309.             base->next = base->prev = base;
  310.             base->length = 0;
  311.             base->data = NULL;
  312.             do_grep(WINDOW[CURWINDOW].base,base,a,(choice == (int)COM_GREP),GREPMODE);
  313.             save_curwindow = CURWINDOW;
  314.             i = dir_depth(WINDOW[CURWINDOW].filename);
  315.             if(grepdata[i])
  316.             {
  317.                 toss_data(grepdata[i]);
  318.                 grepdata[i] = NULL;
  319.             }
  320.             if(greptitle[i])
  321.             {
  322.                 ifree(greptitle[i]);
  323.                 greptitle[i] = NULL;
  324.             }
  325.             if(WINDOW[CURWINDOW].diredit)
  326.             {
  327.                 sprintf(title,"%s - %s window for string '%s'",WINDOW[CURWINDOW].filename,(choice == (int)COM_GREP)? "GREP" : "PERG",a);
  328.                 grepdata[i] = (rec_ptr)imalloc(sizeof(rec_node));
  329.                 grepdata[i]->length = 0;
  330.                 grepdata[i]->data = NULL;
  331.                 copy_records(base,grepdata[i],0,0);
  332.                 greptitle[i] = (Char *)imalloc(strlen(title) + 1);
  333.                 strcpy(greptitle[i],title);
  334.             }
  335.             else
  336.                 sprintf(title,"%s window for string '%s'",(choice == (int)COM_GREP)? "GREP" : "PERG",a);
  337.             save_window();
  338.             insert_window(title,base,0,0);    /* note, this routine may call set_window in order to scroll reduced windows */
  339.             set_non_subp();
  340.             WINDOW[CURWINDOW].diredit = WINDOW[save_curwindow].diredit;
  341.             return(0);
  342.         case COM_BYTE:
  343.             if(WINDOW[CURWINDOW].diredit)
  344.             {
  345.                 bell();
  346.                 slip_message("You cannot insert data into a directory, sorry.");
  347.                 wait_message();
  348.                 break;
  349.             }
  350.             i = parse_decimal(buf + i,l - i);
  351.             if(i > 255)
  352.                 i = 255;
  353.             if(i < 0)
  354.                 i = 0;
  355.             copy_only(0);
  356.             multibuf.nrecs = multibuf.direction = 1;
  357.             multibuf.first = &multirec;    /* initialize repeated-char buffer */
  358.             multibuf.last = &multirec;
  359.             multirec.next = (rec_ptr)&multibuf;
  360.             multirec.prev = (rec_ptr)&multibuf;
  361.             multirec.length = 1;
  362.             multirec.data = buf;
  363.             multirec.data[0] = i;
  364.             insert(&multibuf);
  365.             break;
  366.         case COM_FILE:
  367.             if(strlen(a = parse_string(buf + i,l - i)))    /* parse any additional info following the FILE command */
  368.                 strcpy(bookbuf,a);
  369.             else
  370.                 strcpy(bookbuf,"name");
  371.             bookbuf[0] = tolower(bookbuf[0]);
  372.             buffer_empty(&KILLBUF);
  373.             r.next = &r;
  374.             r.prev = &r;
  375.             if(WINDOW[CURWINDOW].diredit)
  376.             {
  377.                 if(CURREC == BASE)
  378.                 {
  379.                     abort_key();
  380.                     bell();
  381.                     break;
  382.                 }
  383.                 switch(bookbuf[0])
  384.                 {
  385.                     case 'd':
  386.                         strcpy(fname,WINDOW[CURWINDOW].filename);
  387.                         break;
  388.                     case 'n':
  389.                         strcpy(fname,CURREC->data + filename_offset());
  390.                         break;
  391.                     default:
  392.                         strcpy(fname,WINDOW[CURWINDOW].filename);
  393.                         strcat(fname,CURREC->data + filename_offset());
  394.                 }
  395.             }
  396.             else
  397.             {
  398.                 strcpy(fname,WINDOW[CURWINDOW].filename);
  399. #ifndef NO_FTP
  400.                 if((i = host_in_name(fname)))
  401.                 {
  402.                     a = host_filename(i,fname,fname2);
  403.                     if(*((b = fname2 + strlen(fname2) - 1)) == '/')
  404.                         *b = '\0';
  405.                     if(ftp_unixy(ftp_system(fname2)))
  406.                     {
  407.                         for(b = fname2 + strlen(fname2);--b != fname2;)
  408.                             if(*b == '/' || *b == '\\')
  409.                                 break;
  410.                     }
  411.                     else
  412.                     {
  413.                         for(b = fname2 + strlen(fname2);--b != fname2;)
  414.                             if(*b == ']' || *b == '>' || *b == ':')
  415.                                 break;
  416.                     }
  417.                     switch(bookbuf[0])
  418.                     {
  419.                         case 'd':
  420.                             *++b = '\0';
  421.                             strcpy(fname,fname2);
  422.                             break;
  423.                         case 'n':
  424.                             strcpy(fname,++b);
  425.                             break;
  426.                         default:
  427.                             strcpy(fname,fname2);
  428.                             break;
  429.                     }
  430.                 }
  431.                 else
  432. #endif
  433.                 {
  434.                     switch(bookbuf[0])
  435.                     {
  436.                         case 'd':
  437.                             *(filename(fname)) = '\0';
  438.                             break;
  439.                         case 'n':
  440.                             strcpy(bookbuf,filename(fname));
  441.                             strcpy(fname,bookbuf);
  442.                             break;
  443.                         default:
  444.                             break;
  445.                     }
  446.                 }
  447.             }
  448.             if((r.length = strlen(fname)))
  449.             {
  450.                 r.data = (Char *)imalloc(r.length + 1);
  451.                 strcpy(r.data,fname);
  452.                 buffer_append(&KILLBUF,&r,0,r.length);
  453.                 KILLBUF.nrecs = KILLBUF.direction = 1;
  454.                 ifree(r.data);
  455.             }
  456.             break;
  457.         case COM_TRIM:
  458.             if(WINDOW[CURWINDOW].diredit)
  459.             {
  460.                 bell();
  461.                 slip_message("You cannot TRIM a directory listing.");
  462.                 wait_message();
  463.                 break;
  464.             }
  465.             trim();
  466.             break;
  467.         case COM_CD:
  468.             if(strlen(a = parse_string(buf + i,l - i)))    /* parse directory name */
  469.                 strcpy(fname,a);
  470.             else
  471.             {
  472.                 if((l = inquire("Directory to move to",buf,sizeof(buf),1)) > 0)
  473.                     strcpy(fname,buf);
  474.                 else
  475.                     fname[0] = '\0';
  476.             }
  477.             if(fname[0])
  478.             {
  479.                 strip_quotes(fname);
  480.                 envir_subs(fname);
  481.                 if(chdir(fname) < 0)
  482.                 {
  483.                     sprintf(title,"Couldn't change to directory %s.",fname);
  484.                     slip_message(title);
  485.                     wait_message();
  486.                 }
  487.             }
  488.             break;
  489.         case COM_PWD:
  490. #ifdef NeXT
  491.             if(!getwd(fname))
  492. #else
  493.             if(!getcwd(fname,sizeof(fname)))
  494. #endif
  495.             {
  496.                 slip_message("I am unable to get the CWD for some reason.");
  497.                 wait_message();
  498.             }
  499.             else
  500.             {
  501.                 sprintf(title,"Current directory: %s",fname);
  502.                 slip_message(title);
  503.                 wait_message();
  504.             }
  505.             break;
  506.         case COM_BIGGER:
  507.             if(!(i = parse_decimal(buf + i,l - i)))
  508.                 i = 1;
  509.             if(i > 0)
  510.                 bigger_window(i);
  511.             else
  512.                 smaller_window(-i);
  513.             break;
  514.         case COM_SMALLER:
  515.             if(!(i = parse_decimal(buf + i,l - i)))
  516.                 i = 1;
  517.             if(i > 0)
  518.                 smaller_window(i);
  519.             else
  520.                 bigger_window(-i);
  521.             break;
  522.         case COM_LOAD:
  523.             if(strlen(a = parse_string(buf + i,l - i)))
  524.                 strcpy(fname,a);
  525.             else
  526.             {
  527.                 if((l = inquire("File to load key definitions from",buf,sizeof(buf),1)) > 0)
  528.                     strcpy(fname,buf);
  529.                 else
  530.                     fname[0] = '\0';
  531.             }
  532.             if(fname[0])
  533.             {
  534.                 strip_quotes(fname);
  535.                 envir_subs(fname);
  536.                 load_defs(fname);
  537.             }
  538.             break;
  539.         case COM_UNLOAD:
  540.             if(strlen(a = parse_string(buf + i,l - i)))
  541.                 strcpy(fname,a);
  542.             else
  543.             {
  544.                 if((l = inquire("File to unload key definitions to",buf,sizeof(buf),1)) > 0)
  545.                     strcpy(fname,buf);
  546.                 else
  547.                     fname[0] = '\0';
  548.             }
  549.             if(fname[0])
  550.             {
  551.                 strip_quotes(fname);
  552.                 envir_subs(fname);
  553.                 unload_defs(fname);
  554.             }
  555.             break;
  556.         case COM_SORT:
  557.             if(tolower(buf[0]) == 's')
  558.                 if(tolower(buf[1]) == 'o')
  559.                     if(tolower(buf[2]) == 'r')
  560.                         if(tolower(buf[3]) == 't')
  561.                         {
  562.                             j = 0;
  563.                             if(strlen(a = parse_string(buf + i,l - i)))
  564.                                 if(tolower(*a) == 'r')
  565.                                     j = 1;
  566.                             sort_recs(j);
  567.                             break;
  568.                         }
  569.             slip_message("You cannot abbreviate the SORT command; it's too dangerous.");
  570.             wait_message();
  571.             break;
  572. #ifndef GNUDOS
  573.         case COM_BOOKMARK:
  574.             strcpy(bookbuf,WINDOW[CURWINDOW].filename);
  575.             strcat(bookbuf,"-EDbookmark");
  576.             WINDOW[CURWINDOW].bookmark = (Char *)imalloc(strlen(bookbuf) + 1);
  577.             strcpy(WINDOW[CURWINDOW].bookmark,bookbuf);
  578.             save_window();
  579.             update_bookmark(CURWINDOW);
  580.             break;
  581. #endif
  582.         case COM_DELETE:
  583.             if(!WINDOW[CURWINDOW].diredit)
  584.             {
  585.                 slip_message("The DELETE command only applies to directory-mode windows.");
  586.                 wait_message();
  587.                 break;
  588.             }
  589. /* insure some deletions exist */
  590.             p = q = WINDOW[CURWINDOW].base;
  591.             for(p = p->next;p != q;p = p->next)
  592.                 if(p->recflags & 2)
  593.                     break;
  594.             if(p == q)
  595.             {
  596.                 slip_message("There are no files marked for deletion.");
  597.                 wait_message();
  598.             }
  599.             else
  600.             {
  601. /* require the first four characters of 'delete' */
  602.                 if(tolower(buf[0]) == 'd')
  603.                     if(tolower(buf[1]) == 'e')
  604.                         if(tolower(buf[2]) == 'l')
  605.                             if(tolower(buf[3]) == 'e')
  606.                             {
  607. /* scan the buffer and delete them */
  608.                                 p = q = WINDOW[CURWINDOW].base;
  609.                                 for(count = 0,p = p->next;p != q;p = p->next)
  610.                                     if(p->recflags & 2)
  611.                                         if(strcmp(p->data + filename_offset(),"..") && strcmp(p->data + filename_offset(),"[-]"))
  612.                                         {
  613.                                             strcpy(fname,WINDOW[CURWINDOW].filename);
  614.                                             strcat(fname,p->data + filename_offset());
  615. #ifndef NO_FTP
  616.                                             if(host_in_name(fname))
  617.                                             {
  618.                                                 sprintf(buf,"DELE %s",p->data + filename_offset());
  619.                                                 if(!ftp_command(buf))
  620.                                                     goto delete_error;
  621.                                             }
  622.                                             else
  623. #endif
  624.                                             {
  625. #ifdef VMS
  626.                                                 desc.string = fname;
  627.                                                 desc.length = strlen(fname);
  628.                                                 desc.class = 0x010e;
  629.                                                 if(!(LIB$DELETE_FILE(&desc) & 1))
  630. #else
  631.                                                 if(remove(fname))
  632. #endif
  633.                                                 {
  634. delete_error:
  635.                                                     sprintf(fname,"Unable to delete file %s, aborting.",p->data + filename_offset());
  636.                                                     slip_message(fname);
  637.                                                     wait_message();
  638.                                                     break;
  639.                                                 }
  640.                                             }
  641.                                             count++;
  642.                                         }
  643. /* re-create the buffer, which should be different now */
  644.                                 if(count)
  645.                                 {
  646.                                     base = (rec_ptr)imalloc(sizeof(rec_node));
  647.                                     base->length = 0;
  648.                                     base->data = NULL;
  649.                                     base->prev = base->next = base;
  650.                                     if(read_in_diredit(fname,WINDOW[CURWINDOW].filename,base))
  651.                                     {
  652.                                         toss_data(BASE);
  653.                                         BASE = base;
  654.                                         CURROW = TOPROW;
  655.                                         CURCOL = 1;
  656.                                         FIRSTCOL = 1;
  657.                                         WANTCOL = 1;
  658.                                         DIRECTION = 1;
  659.                                         SELREC = 0;
  660.                                         TOPREC = BOTREC = CURREC = BASE->next;
  661.                                         for(i = TOPROW;i < BOTROW;i++)    /* establish BOTREC */
  662.                                         {
  663.                                             if(BOTREC == BASE)
  664.                                                 break;
  665.                                             BOTREC = BOTREC->next;
  666.                                         }
  667.                                         if(i < BOTROW)
  668.                                             BOTREC = 0;
  669.                                         ifree(WINDOW[CURWINDOW].filename);
  670.                                         WINDOW[CURWINDOW].filename = (Char *)imalloc(strlen(fname) + 1);    /* this line cannot be merged with the following one... */
  671.                                         strcpy(WINDOW[CURWINDOW].filename,fname);    /* ...without generating a pointer mismatch error under VMS cc */
  672.                                         WINDOW[CURWINDOW].base = BASE;
  673.                                         dir_store(CURWINDOW,WINDOW[CURWINDOW].filename,BASE);
  674.                                         save_window();
  675.                                         ref_window(CURWINDOW);
  676.                                     }
  677.                                     else
  678.                                     {
  679.                                         ifree(base);
  680.                                         bell();
  681.                                         slip_message("I was unable to re-read the directory. Deleted files may persist.");
  682.                                         wait_message();
  683.                                     }
  684.                                 }
  685.                                 break;
  686.                             }
  687.                 slip_message("You cannot abbreviate the DELETE command; it's too dangerous.");
  688.                 wait_message();
  689.             }
  690.             break;
  691.         case COM_SUBSTITUTE:
  692.             if(WINDOW[CURWINDOW].diredit)
  693.             {
  694.                 bell();
  695.                 slip_message("You cannot make substitutions in a directory listing.");
  696.                 wait_message();
  697.                 break;
  698.             }
  699.             if(strlen(a = parse_string(buf + i,l - i)))
  700.                 strcpy(fname,a);
  701.             else
  702.             {
  703.                 if((l = inquire("Substitution command",buf,sizeof(buf),1)) > 0)
  704.                     strcpy(fname,buf);
  705.                 else
  706.                     fname[0] = '\0';
  707.             }
  708.             if((i = fname[0]))    /* c will be the delimiter */
  709.             {
  710.                 if(!(a = strchr(fname + 1,i)))
  711.                     goto subst_err;
  712.                 if(!(b = strchr(a + 1,i)))
  713.                     goto subst_err;
  714.                 *a++ = '\0';
  715.                 *b = '\0';
  716.                 if(!strlen(fname + 1))
  717.                     goto subst_err;
  718.                 if(SEARCH_FLAGS[((int)SMODE_BEGINNING) >> 1] == 'b')    /* if they are in beginning mode, work backwards from the end of file */
  719.                 {
  720.                     emulate_key((Schar)KEY_ENDOFFILE,1);
  721.                     emulate_key((Schar)KEY_FIND,1);
  722.                     for(c = fname + 1;(i = *c++);)
  723.                         emulate_key((Schar)i,1);
  724.                     emulate_key((Schar)KEY_BACKWARD,1);
  725.                 }
  726.                 else    /* if they are in end mode, work forward from the top of file */
  727.                 {
  728.                     emulate_key((Schar)KEY_TOPOFFILE,1);
  729.                     emulate_key((Schar)KEY_FIND,1);
  730.                     for(c = fname + 1;(i = *c++);)
  731.                         emulate_key((Schar)i,1);
  732.                     emulate_key((Schar)KEY_FORWARD,1);
  733.                 }
  734.                 emulate_key((Schar)KEY_SELECT,1);
  735.                 for(c = a;(i = *c++);)
  736.                     emulate_key((Schar)i,1);
  737.                 emulate_key((Schar)KEY_KILL,1);
  738.                 emulate_key((Schar)KEY_SUBSTITUTE,0x7fffffff);
  739.             }
  740.             break;
  741. subst_err:
  742.             slip_message("The SUBST command requires a string of the form: /string1/string2/");
  743.             slip_message("You can replace '/' with any character not appearing in string1 or string2.");
  744.             wait_message();
  745.             break;
  746.         default:    /* error parsing command */
  747.             return(0);
  748.     }
  749.     paint(BOTROW,BOTROW,FIRSTCOL);
  750.     return(0);
  751. }
  752.  
  753.